package com.zzh.lib.recorder.ui;

import static com.zzh.lib.recorder.utils.LameUtils.getStorageMp4;
import static com.zzh.lib.recorder.utils.MatrixUtils.DELAY_DELTA;
import static com.zzh.lib.recorder.utils.MatrixUtils.OVER_CLICK;
import static com.zzh.lib.recorder.utils.MatrixUtils.RECORD_MIN_TIME;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.fragment.app.Fragment;

import com.zzh.lib.htts.R;
import com.zzh.lib.recorder.camera.CameraRecorder;
import com.zzh.lib.recorder.camera.CameraRecorderBuilder;
import com.zzh.lib.recorder.def.CameraRecordListener;
import com.zzh.lib.recorder.model.MediaObject;
import com.zzh.lib.recorder.params.LensFacing;
import com.zzh.lib.recorder.utils.LameUtils;
import com.zzh.lib.recorder.view.CustomRecordImageView;
import com.zzh.lib.recorder.view.ProgressView;
import com.zzh.lib.recorder.view.SampleGLView;

import java.lang.ref.WeakReference;

public class RecorderFragment extends Fragment implements CameraRecordListener {
    private static final int VIDEO_MAX_TIME = 60 * 1000;

    protected SampleGLView sampleGLView;
    protected CameraRecorder cameraRecorder;

    protected LensFacing lensFacing = LensFacing.BACK;
    protected int videoWidth = 720;
    protected int videoHeight = 1280;
    protected int cameraWidth = 1280;
    protected int cameraHeight = 720;
    protected boolean toggleClick = false;

    protected ProgressView mVideoRecordProgressView;
    protected TextView mVideoRecordFinishIv;
    protected ImageView mMeetCamera;
    protected LinearLayout mIndexDelete;
    protected CustomRecordImageView mCustomRecordImageView;
    protected FrameLayout mRecordBtnLl;

    protected long mLastTime = 0;
    private MediaObject mMediaObject;

    protected final MyHandler mMyHandler = new MyHandler(this);
    protected boolean isRecording = false;

    protected int setLayoutId() {
        return R.layout.h_lib_frag_recorder;
    }

    @Override
    public void onResume() {
        super.onResume();
        mVideoRecordProgressView.setData(mMediaObject);
        setUpCamera();
    }

    View mContainerView;
    FrameLayout cameraContainerView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (mContainerView == null) {
            mContainerView = inflater.inflate(setLayoutId(), container, false);
            initView();
            setListener();
        }
        return mContainerView;
    }


    protected void setListener() {
        mVideoRecordFinishIv.setOnClickListener(this::onViewClicked);
        mMeetCamera.setOnClickListener(this::onViewClicked);
        mIndexDelete.setOnClickListener(this::onViewClicked);
        mCustomRecordImageView.setOnClickListener(this::onViewClicked);
    }

    protected int recordVideoTime = 60;
    protected String recordVideoDir;

    public void initView() {

        Bundle args = getArguments();
        cameraContainerView = mContainerView.findViewById(R.id.fl_camera_container);
        mVideoRecordProgressView = mContainerView.findViewById(R.id.video_record_progress_view);
        mVideoRecordFinishIv = mContainerView.findViewById(R.id.video_record_finish_iv);
        mMeetCamera = mContainerView.findViewById(R.id.switch_camera);
        mIndexDelete = mContainerView.findViewById(R.id.index_delete);
        mCustomRecordImageView = mContainerView.findViewById(R.id.custom_record_image_view);
        mRecordBtnLl = mContainerView.findViewById(R.id.record_btn_ll);

        if (mMediaObject == null) {
            mMediaObject = new MediaObject();
        }

        recordVideoTime = 60;

        if (args != null) {
            recordVideoTime = args.getInt("record_video_time", 60);
            recordVideoDir = args.getString("record_video_dir");
        }
        if (recordVideoTime < 5) {
            recordVideoTime = 60;
        }
        if (TextUtils.isEmpty(recordVideoDir)) {
            recordVideoDir = LameUtils.createVideoDir();
        }

        mVideoRecordProgressView.setMaxDuration(recordVideoTime * 1000, false);
        mVideoRecordProgressView.setOverTimeClickListener(new ProgressView.OverTimeClickListener() {
            @Override
            public void overTime() {
                mCustomRecordImageView.performClick();
            }

            @Override
            public void noEnoughTime() {
                //时长不够
            }

            @Override
            public void isArriveCountDown() {
                mCustomRecordImageView.performClick();
            }
        });
    }

    protected String videoFileName;

    public void onViewClicked(View view) {
        if (System.currentTimeMillis() - mLastTime < 500) {
            return;
        }
        mLastTime = System.currentTimeMillis();
        if (view.getId() != R.id.index_delete) {
            if (mMediaObject != null) {
                MediaObject.MediaPart part = mMediaObject.getCurrentPart();
                if (part != null) {
                    if (part.remove) {
                        part.remove = false;
                        if (mVideoRecordProgressView != null)
                            mVideoRecordProgressView.invalidate();
                    }
                }
            }
        }
        int id = view.getId();
        if (id == R.id.video_record_finish_iv) {
            boolean recordVideo = finishRecordVideo();
            if (recordVideo) {
                Intent data = new Intent();
                data.putExtra("videoPath", videoFileName);
                requireActivity().setResult(Activity.RESULT_OK, data);
                requireActivity().finish();
            }
        } else if (id == R.id.switch_camera) {
            if (!isRecording) {
                //切换摄像头
                releaseCamera();
                if (lensFacing == LensFacing.BACK) {
                    lensFacing = LensFacing.FRONT;
                } else {
                    lensFacing = LensFacing.BACK;
                }
                toggleClick = true;
            }

        } else if (id == R.id.index_delete) {
            MediaObject.MediaPart part = mMediaObject.getCurrentPart();
            if (part != null) {
                if (part.remove) {
                    part.remove = false;
                    mMediaObject.removePart(part, true);
                    if (mMediaObject.getMedaParts().size() == 0) {
                        mIndexDelete.setVisibility(View.GONE);
                        mVideoRecordFinishIv.setVisibility(View.GONE);
                    }
                    if (mMediaObject.getDuration() < RECORD_MIN_TIME) {
                        mVideoRecordProgressView.setShowEnouchTime(false);
                    }
                } else {
                    part.remove = true;
                }
            }
        } else if (id == R.id.custom_record_image_view) {
            if (!isRecording) {
                onStartRecording();
            } else {
                onStopRecording();
            }
        }
    }

    protected boolean finishRecordVideo() {
        onStopRecording();
        if (mMediaObject != null) {
            videoFileName = mMediaObject.mergeVideo();
        }
        return true;
    }

    protected void releaseCamera() {
        if (sampleGLView != null) {
            sampleGLView.onPause();
        }

        if (cameraRecorder != null) {
            cameraRecorder.stop();
            cameraRecorder.release();
            cameraRecorder = null;
        }

        if (sampleGLView != null) {
            cameraContainerView.removeView(sampleGLView);
            sampleGLView = null;
        }
    }

    protected void setUpCameraView() {
        requireActivity().runOnUiThread(() -> {
            cameraContainerView.removeAllViews();
            sampleGLView = null;
            sampleGLView = new SampleGLView(requireActivity());
            sampleGLView.setTouchListener((event, width, height) -> {
                if (cameraRecorder == null) return;
                cameraRecorder.changeManualFocusPoint(event.getX(), event.getY(), width, height);
            });
            cameraContainerView.addView(sampleGLView);
        });
    }

    protected void setUpCamera() {
        setUpCameraView();
        cameraRecorder = new CameraRecorderBuilder(requireActivity(), sampleGLView)
                .cameraRecordListener(this)
                .mute(true)
                .videoSize(videoWidth, videoHeight)
                .cameraSize(cameraWidth, cameraHeight)
                .lensFacing(lensFacing)
                .build();


    }

    protected void openFlash() {
        if (cameraRecorder != null && cameraRecorder.isFlashSupport()) {
            cameraRecorder.switchFlashMode();
            cameraRecorder.changeAutoFocus();
        }
    }

    protected void onStartRecording() {
        isRecording = true;
        String storageMp4 = getStorageMp4(recordVideoDir, String.valueOf(System.currentTimeMillis()));
        mMediaObject.buildMediaPart(storageMp4);
        //开始录制
        cameraRecorder.start(storageMp4);

        mCustomRecordImageView.startRecord();
        mVideoRecordProgressView.start();
        alterStatus();
    }

    protected void onStopRecording() {
        isRecording = false;
        //停止录制
        cameraRecorder.stop();
        mVideoRecordProgressView.stop();
        // 录制释放有延时，稍后处理
        mMyHandler.sendEmptyMessageDelayed(DELAY_DELTA, 250);
        mCustomRecordImageView.stopRecord();
        alterStatus();
    }

    protected void showOtherView() {
        if (mMediaObject != null && mMediaObject.getMedaParts().size() == 0) {
            mIndexDelete.setVisibility(View.GONE);
            mVideoRecordFinishIv.setVisibility(View.GONE);
        } else {
            mIndexDelete.setVisibility(View.VISIBLE);
            mVideoRecordFinishIv.setVisibility(View.VISIBLE);
        }
        mCustomRecordImageView.setVisibility(View.VISIBLE);
    }

    protected void hideOtherView() {
        mIndexDelete.setVisibility(View.INVISIBLE);
        mVideoRecordFinishIv.setVisibility(View.INVISIBLE);
        mCustomRecordImageView.setVisibility(View.INVISIBLE);
    }

    //正在录制中
    public void alterStatus() {
        if (isRecording) {
            mIndexDelete.setVisibility(View.INVISIBLE);
            mVideoRecordFinishIv.setVisibility(View.INVISIBLE);
        } else {
            if (mMediaObject != null && mMediaObject.getMedaParts().size() == 0) {
                mIndexDelete.setVisibility(View.GONE);
                mVideoRecordFinishIv.setVisibility(View.GONE);
            } else {
                mIndexDelete.setVisibility(View.VISIBLE);
                mVideoRecordFinishIv.setVisibility(View.VISIBLE);

            }
            mMeetCamera.setVisibility(View.VISIBLE);
            mVideoRecordProgressView.setVisibility(View.VISIBLE);
        }
    }

    protected void hideAllView() {
        hideOtherView();
        mVideoRecordFinishIv.setVisibility(View.GONE);
        mVideoRecordProgressView.setVisibility(View.GONE);
        mMeetCamera.setVisibility(View.GONE);
    }


    @Override
    public void onDestroyView() {
        releaseCamera();
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        try {
            mMyHandler.removeCallbacksAndMessages(null);
        } catch (Exception ex) {

        }
        super.onDestroy();
    }

    @Override
    public void onGetFlashSupport(boolean flashSupport) {

    }

    @Override
    public void onRecordComplete() {

    }

    @Override
    public void onRecordStart() {

    }

    @Override
    public void onError(Exception exception) {

    }

    @Override
    public void onCameraThreadFinish() {
        if (toggleClick) {
            requireActivity().runOnUiThread(() -> {
                setUpCamera();
            });
        }
        toggleClick = false;
    }


    private static class MyHandler extends Handler {

        private final WeakReference<RecorderFragment> mVideoRecordActivity;

        public MyHandler(RecorderFragment videoRecordActivity) {
            mVideoRecordActivity = new WeakReference<>(videoRecordActivity);
        }

        @Override
        public void handleMessage(Message msg) {
            RecorderFragment activity = mVideoRecordActivity.get();
            if (activity != null) {
                switch (msg.what) {
                    case DELAY_DELTA:
                        activity.mMediaObject.stopRecord(activity.mMediaObject);
                        break;
                    case OVER_CLICK:
                        activity.mCustomRecordImageView.performClick(); //定时结束
                        break;
                }
            }
        }
    }
}
